//
//  OptionsViewController.swift
//  Automobile
//
//  Created by erkebulan elzhan on 8/3/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.


import UIKit
import SnapKit

protocol OptionsViewControllerDelegate : class {
    func didSelectedOptions (options: [String : Any]?, filterFormat: [String]?)
}

final class OptionsViewController: UIViewController {

    // MARK: - Outlets
    
    private lazy var submitButton: UIButton = {
        let btn = UIButton()
        btn.clipsToBounds = true
        btn.layer.cornerRadius = 15
        btn.backgroundColor = .blueColor
        btn.setTitleColor(.white, for: .normal)
        btn.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .medium)
        btn.setTitle("Далее", for: .normal)
        return btn
    }()
    
    private lazy var tableView: UITableView = {
        let tableView = UITableView()
        self.view.backgroundColor = .whiteBlueColor
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(SingleFieldCell.self, forCellReuseIdentifier: "SingleFieldCell")
        tableView.register(ChoiceFieldCell.self, forCellReuseIdentifier: "ChoiceFieldCell")
        tableView.register(MultipleFieldCell.self, forCellReuseIdentifier: "MultipleFieldCell")
        tableView.backgroundColor = .whiteBlueColor
        tableView.separatorStyle = .none
        return tableView
    }()
    
    private lazy var spinnerView = SpinnerView()
    
    // MARK: - Props
    
    weak var callbackVC: OptionsViewControllerDelegate!
    private var optionsModel = OptionsModel()
    
    private var isLoading: Bool = false {
        didSet {
            isLoading ? spinnerView.startAnimating() : spinnerView.stopAnimating()
            view.isUserInteractionEnabled = !isLoading
        }
    }
    
    public var updateSelectedItemsAfterFetch = false
    
    public var filterOptions: [String] = []
    
    // MARK: - Actions
    
    @objc private func onReady (sender: UIButton) {
        
        if callbackVC is FilterViewController {
            callbackVC.didSelectedOptions(options: nil, filterFormat: optionsModel.getFilterQuery())
        } else {
            callbackVC.didSelectedOptions(options: optionsModel.getResultOptions(), filterFormat: nil)
        }

        self.navigationController?.popViewController(animated: true)
    }
    
    @objc private func goBack (sender: Any) {
        self.navigationController?.popViewController(animated: true)
    }
    
    @objc private func onReset (sender: Any) {
        optionsModel.resetOptions { (_) in
            self.tableView.reloadSections(IndexSet(arrayLiteral: 0), with: .top)
        }
    }
    
    // MARK: - Init
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.tableFooterView = self.getFooterView()
        self.loadData(updateSelection: updateSelectedItemsAfterFetch)
        self.addViews()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.setUpNavBar()
    }
}


extension OptionsViewController {
    private func importOptions (singleOptions: String, choiceOptions: String, multipleOptions: String) {
        optionsModel.importOptions(singleOptions: singleOptions, choiceOptions: choiceOptions, multipleOptions: multipleOptions)
    }
}



extension OptionsViewController {
    
    private func addViews () {
        self.view.addSubview(tableView)
        self.view.addSubview(spinnerView)
        tableView.snp.makeConstraints { (make) in
            make.top.bottom.equalTo(view.safeAreaLayoutGuide)
            make.leading.trailing.equalToSuperview()
        }
        spinnerView.snp.makeConstraints { (make) in
            make.center.equalToSuperview()
        }
    }
    
    private func setUpNavBar() {
        self.navigationController?.navigationBar.isHidden = false
        self.navigationController?.navigationBar.defaultNavBar()
    
        let backIcon = UIImage(named: "cancel")
        let backButton = UIBarButtonItem(image: backIcon, landscapeImagePhone: backIcon, style: .plain, target: self, action: #selector(goBack(sender:)))
        backButton.tintColor = .greyColor
        
        let resetBtn = UIBarButtonItem(title: "Сбросить", style: .plain, target: self, action: #selector(onReset(sender:)))
        self.navigationItem.rightBarButtonItem = resetBtn
        
        self.navigationItem.simpleNavBar(title: "Опции", backButton: backButton)
    }
    
    private func loadData (updateSelection: Bool) {
        self.isLoading = true
        optionsModel.loadOptions { (isSuccess) in
            self.isLoading = false
            if (updateSelection && self.filterOptions.count == 3) {
                self.importOptions(singleOptions: self.filterOptions[0], choiceOptions: self.filterOptions[1], multipleOptions: self.filterOptions[2])
            }
            self.tableView.reloadData()
        }
    }
    
    private func getFooterView () -> UIView {
        let footerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 110))
        footerView.addSubview(submitButton)
        submitButton.addTarget(self, action: #selector(onReady(sender:)), for: .touchUpInside)
        submitButton.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview().inset(16)
            make.height.equalTo(44)
            make.bottom.equalToSuperview().offset(-20)
        }
        return footerView
    }
}


// MARK: - Table View Configuration


extension OptionsViewController: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let currentData = optionsModel.allRows[indexPath.section][indexPath.row]

        if currentData is SingleField {
            var copy = currentData as! SingleField
            copy.isSelected.toggle()
            optionsModel.allRows[indexPath.section][indexPath.row] = copy
        }
        tableView.reloadData()
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let currentData = optionsModel.allRows[indexPath.section][indexPath.row]
        
        if currentData is ChoiceField {
            
            let cell = tableView.dequeueReusableCell(withIdentifier: "ChoiceFieldCell") as! ChoiceFieldCell
            cell.data = (currentData as! ChoiceField)
            cell.delegate = self
            cell.indexPath = indexPath
            cell.addTap()
            cell.contentView.backgroundColor = .whiteBlueColor
            
            return cell
        } else if currentData is SingleField {
            
            let cell = tableView.dequeueReusableCell(withIdentifier: "SingleFieldCell") as! SingleFieldCell
            cell.data = currentData as? SingleField
            cell.contentView.backgroundColor = .whiteBlueColor
            
            return cell
        } else {
            
            let cell = tableView.dequeueReusableCell(withIdentifier: "MultipleFieldCell") as! MultipleFieldCell
            cell.data = currentData as? MultipleField
            cell.delegate = self
            cell.indexPath = indexPath
            cell.addTap()
            cell.contentView.backgroundColor = .whiteBlueColor
            
            return cell
        }
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return optionsModel.sectionData.1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return optionsModel.allRows[section].count
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 40))
        view.backgroundColor = .whiteBlueColor
        let title = optionsModel.sectionData.0[section]
        let lbl = UILabel()
        lbl.font = UIFont.systemFont(ofSize: 18, weight: .bold)
        lbl.text = title
        view.addSubview(lbl)
        
        lbl.snp.makeConstraints { (make) in
            make.centerY.equalToSuperview()
            make.leading.trailing.equalToSuperview().inset(16)
        }
        
        return view
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 40.0
    }
}


// MARK: - Cell Config


extension OptionsViewController: OptionCellDelegate {
    
    func didSelectCell(at indexPath: IndexPath, optionIndex: Int?) {
        let currentData = optionsModel.allRows[indexPath.section][indexPath.row]
        
        if currentData is ChoiceField {
            var copy = currentData as! ChoiceField
            if let _optionIndex = optionIndex {
                 copy.selectedId = copy.fields[_optionIndex].id
            } else {
                copy.isExpanded.toggle()
            }
            
            optionsModel.allRows[indexPath.section][indexPath.row] = copy
        } else if currentData is MultipleField {
            var copy = currentData as! MultipleField
            
            if let _optionIndex = optionIndex {
                
                if let index = copy.selectedItems.firstIndex(of: copy.fields[_optionIndex].id) {
                    copy.selectedItems.remove(at: index)
                } else {
                    copy.selectedItems.append(copy.fields[_optionIndex].id)
                }

            } else {
                copy.isExpanded.toggle()
            }
            
            optionsModel.allRows[indexPath.section][indexPath.row] = copy
        }
        
        tableView.reloadData()
    }
}
